#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;

const int MAXN = 100005;
int T;
int n, m, l, v, carcnt;
int di[MAXN], vi[MAXN], ai[MAXN], cntc[MAXN], p[MAXN];
struct node{
    int num, id;
    vector <int> cars;
} cam[MAXN];

bool cmp(node a, node b){
    if (a.num == b.num) return a.id < b.id;
    return a.num < b.num;
}

int main(){
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);

    scanf("%d", &T);
    while (T--)
    {
        carcnt = 0;
        memset(cntc, 0, sizeof(cntc));
        memset(p, 0, sizeof(p));
        scanf("%d%d%d%d", &n, &m, &l, &v);
        for (int i=1; i<=n; i++) scanf("%d%d%d", &di[i], &vi[i], &ai[i]);
        for (int i=1; i<=m; i++) cin >> p[i];
        for (int i=1; i<=n; i++){
            double s=-1, e=-1;
            if (vi[i] > v && ai[i] >= 0){
                s = di[i]; e = l;
                // printf("type1\n");
                // cout << vi[i] << " " << v << " " << ai[i] << endl;
            }    
            if (vi[i] > v && ai[i] < 0){
                double inspeedt = (vi[i] - v) * 1.0 / (-ai[i]);
                s = di[i], e = vi[i]*inspeedt + 0.5 * ai[i] * inspeedt * inspeedt + di[i];
                // printf("type2\n");
            }
            if (vi[i] <= v && ai[i] > 0){
                double inspeedt = (v - vi[i]) * 1.0 / ai[i];
                s = vi[i]*inspeedt + 0.5 * ai[i] * inspeedt * inspeedt + di[i], e = l;
                // printf("type3\n");
            }

            if (s != -1){
                int scam = lower_bound(p+1, p+n+1, s) - p;
                int ecam = upper_bound(p+1, p+n+1, e) - p - 1;
                if (scam > ecam) continue;
                for (int j=scam; j<=ecam; j++){
                    cam[j].cars.push_back(i);
                    cam[j].num++;
                }
                carcnt++;
                cntc[i] += ecam - scam + 1;
                // cout << s << " " << e << endl;
            }
        }

        int canclose = 0;
        for (int i=1; i<=m; i++){
            cam[i].id = i;
            // printf("cam: %d, num: %d\n", cam[i].id, cam[i].num);
            // for (int j=1; j<=cam[i].cars.size(); j++){
            //     printf("%d ", cam[i].cars[j]);
            // }
            // printf("\n");
        }
        sort(cam+1, cam+m+1, cmp);
        for (int i=1; i<=m; i++){
            int len = cam[i].cars.size();
            bool flag = true;
            for (int j=0; j<len; j++){
                if (cntc[cam[i].cars[j]] <= 1){
                    flag = false;
                    break;
                }
            }
            if (flag){
                for (int j=0; j<len; j++){
                    cntc[cam[i].cars[j]]--;
                }
                canclose++;
            }
            cam[i].cars.clear();
        }
        
        printf("%d %d\n", carcnt, canclose);
    }
    

    fclose(stdin);
    fclose(stdout);
    return 0;
}